package jh.jianguan.springboot.config;

import jh.jianguan.springboot.service.common.impl.SecurityUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.*;


/**
 * @description: 安全模块配置类
 * @author: guoc
 * @createDate: 2020/11/30 11:04
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableAutoConfiguration
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {


    @Resource
    SecurityUserDetailsService securityUserDetailsService;


    /**
     * 用户信息的配置
     * @return void
     * @author guoc
     * @date 2020/11/30 11:18
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //配置默认登陆用户
//                auth
//                .inMemoryAuthentication()
//                .withUser("abner")
//                .password("123")
//                .roles("user")
//                .and()
//                .passwordEncoder(CharEncoder.getINSTANCE());

        //配置数据库认证
        auth
                .userDetailsService(this.securityUserDetailsService)
                .passwordEncoder(passwordEncoder());

    }

    /**
     * 密码加密
     * @return org.springframework.security.crypto.password.PasswordEncoder
     * @author guoc
     * @date 2020/11/30 15:22
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * 以下方式就是设计模式中的单例模式的饿汉式
     * 内部类
     * @return
     * @author guoc
     * @date 2020/11/30 11:09
     */
    public static class CharEncoder implements PasswordEncoder {

        public  static CharEncoder INSTANCE = new CharEncoder();

        public static CharEncoder getINSTANCE(){
            return INSTANCE;
        }

        @Override
        public String encode(CharSequence rawPassword) {
            return rawPassword.toString();
        }

        @Override
        public boolean matches(CharSequence rawPassword, String encodedPassword) {
            return rawPassword.toString().equals(encodedPassword);
        }
    }

    /**
     * 配置如何通过拦截器保护我们的请求，哪些能通过哪些不能通过,
     * 允许对特定的http请求基于安全考虑进行配置
     * @return void
     * @author guoc
     * @date 2020/11/30 11:19
     *
     * anyRequest：对于任何的请求我们都进行拦截认证，
     * permitAll() 方法会对指定的路径放行
     * authenticated() 方法会对指定的路径进行拦截认证，如果未登陆则跳转到登陆页面
     *
     */
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
                httpSecurity
                .authorizeRequests().antMatchers("/").permitAll()
                //SpringSecurity 开放自定义SpringSecurity登陆页面
                .antMatchers("/login.html").permitAll()
                .antMatchers("/login.css").permitAll()
                .antMatchers("/IT.jpg").permitAll()
                //SpringSecurity 开放swagger
                .antMatchers("/swagger-ui.html").permitAll()
                .antMatchers("/webjars/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                .antMatchers("/swagger-resources/**").permitAll()
                .antMatchers("/doc.html").permitAll()
                 //SpringSecurity 开放druid 数据库监控
                .antMatchers("/druid/**").permitAll()
                .anyRequest().authenticated()
                .and()
                //SpringSecurity 关闭csrf，否则druid无法登录
                .csrf().disable()
                //SpringSecurity 开放druid
                .formLogin()
                .loginPage("/login.html")
                .failureUrl("/auth/login?error")
                .loginProcessingUrl("/login");
    }


}
